/******************************************************************************* * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.ui.refactoring; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Table; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.window.Window; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.ISelectionStatusValidator; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeHierarchy; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.search.IJavaSearchConstants; import org.eclipse.jdt.core.search.IJavaSearchScope; import org.eclipse.jdt.core.search.SearchEngine; import org.eclipse.jdt.internal.corext.refactoring.ExceptionInfo; import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.internal.ui.JavaPluginImages; import org.eclipse.jdt.internal.ui.JavaUIStatus; import org.eclipse.jdt.internal.ui.dialogs.FilteredTypesSelectionDialog; import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; import org.eclipse.jdt.internal.ui.util.SWTUtil; import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels; /** * A special control to add and remove thrown exceptions. */ public class ChangeExceptionsControl extends Composite { //TODO: cleanup, adapt NLS strings private static class ExceptionInfoContentProvider implements IStructuredContentProvider { @SuppressWarnings("unchecked") public Object[] getElements(Object inputElement) { return removeMarkedAsDeleted((List<ExceptionInfo>) inputElement); } private ExceptionInfo[] removeMarkedAsDeleted(List<ExceptionInfo> exceptionInfos){ List<ExceptionInfo> result= new ArrayList<ExceptionInfo>(exceptionInfos.size()); for (Iterator<ExceptionInfo> iter= exceptionInfos.iterator(); iter.hasNext();) { ExceptionInfo info= iter.next(); if (! info.isDeleted()) result.add(info); } return result.toArray(new ExceptionInfo[result.size()]); } public void dispose() { // do nothing } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { // do nothing } } private static class ExceptionInfoLabelProvider extends LabelProvider implements ITableLabelProvider { private Image fInterfaceImage; public ExceptionInfoLabelProvider() { super(); fInterfaceImage= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_CLASS); } public Image getColumnImage(Object element, int columnIndex) { return fInterfaceImage; } public String getColumnText(Object element, int columnIndex) { ExceptionInfo info= (ExceptionInfo) element; return BasicElementLabels.getJavaElementName(info.getFullyQualifiedName()); } } private final IExceptionListChangeListener fListener; private final IJavaProject fProject; private TableViewer fTableViewer; private Button fRemoveButton; private List<ExceptionInfo> fExceptionInfos; public ChangeExceptionsControl(Composite parent, int style, IExceptionListChangeListener listener, IJavaProject project) { super(parent, style); Assert.isNotNull(listener); fListener= listener; Assert.isNotNull(project); fProject= project; GridLayout layout= new GridLayout(); layout.numColumns= 2; layout.marginWidth= 0; layout.marginHeight= 0; setLayout(layout); createExceptionList(this); createButtonComposite(this); } public void setInput(List<ExceptionInfo> exceptionInfos) { Assert.isNotNull(exceptionInfos); fExceptionInfos= exceptionInfos; fTableViewer.setInput(fExceptionInfos); if (fExceptionInfos.size() > 0) fTableViewer.setSelection(new StructuredSelection(fExceptionInfos.get(0))); } private void createExceptionList(Composite parent) { final Table table= new Table(parent, SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); table.setLayoutData(new GridData(GridData.FILL_BOTH)); fTableViewer= new TableViewer(table); fTableViewer.setUseHashlookup(true); fTableViewer.setContentProvider(new ExceptionInfoContentProvider()); fTableViewer.setLabelProvider(new ExceptionInfoLabelProvider()); fTableViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { updateButtonsEnabledState(); } }); } private ExceptionInfo[] getSelectedItems() { ISelection selection= fTableViewer.getSelection(); if (selection == null) return new ExceptionInfo[0]; if (!(selection instanceof IStructuredSelection)) return new ExceptionInfo[0]; List<?> selected= ((IStructuredSelection) selection).toList(); return selected.toArray(new ExceptionInfo[selected.size()]); } // ---- Button bar -------------------------------------------------------------------------------------- private void createButtonComposite(Composite parent) { Composite buttonComposite= new Composite(parent, SWT.NONE); buttonComposite.setLayoutData(new GridData(GridData.FILL_VERTICAL)); GridLayout gl= new GridLayout(); gl.marginHeight= 0; gl.marginWidth= 0; buttonComposite.setLayout(gl); createAddButton(buttonComposite); fRemoveButton= createRemoveButton(buttonComposite); updateButtonsEnabledState(); } private void updateButtonsEnabledState() { if (fRemoveButton != null) fRemoveButton.setEnabled(getTableSelectionCount() != 0); } private int getTableSelectionCount() { return getTable().getSelectionCount(); } private int getTableItemCount() { return getTable().getItemCount(); } private Table getTable() { return fTableViewer.getTable(); } private Button createAddButton(Composite buttonComposite) { Button button= new Button(buttonComposite, SWT.PUSH); button.setText(RefactoringMessages.ChangeExceptionsControl_buttons_add); button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); SWTUtil.setButtonDimensionHint(button); button.setEnabled(true); button.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { doAddException(); } }); return button; } private void doAddException() { IType newException= chooseException(); if (newException == null) return; ExceptionInfo info= findExceptionInfo(newException); if (info != null) { if (info.isDeleted()) { info.markAsOld(); fTableViewer.refresh(); } fListener.exceptionListChanged(); fTableViewer.getControl().setFocus(); fTableViewer.setSelection(new StructuredSelection(info), true); return; } info= ExceptionInfo.createInfoForAddedException(newException); fExceptionInfos.add(info); fListener.exceptionListChanged(); fTableViewer.refresh(); fTableViewer.getControl().setFocus(); int row= getTableItemCount() - 1; getTable().setSelection(row); updateButtonsEnabledState(); } private IType chooseException() { IJavaElement[] elements= new IJavaElement[] { fProject.getJavaProject() }; final IJavaSearchScope scope= SearchEngine.createJavaSearchScope(elements); FilteredTypesSelectionDialog dialog= new FilteredTypesSelectionDialog(getShell(), false, PlatformUI.getWorkbench().getProgressService(), scope, IJavaSearchConstants.CLASS); dialog.setTitle(RefactoringMessages.ChangeExceptionsControl_choose_title); dialog.setMessage(RefactoringMessages.ChangeExceptionsControl_choose_message); dialog.setInitialPattern("*Exception*"); //$NON-NLS-1$ dialog.setValidator(new ISelectionStatusValidator() { public IStatus validate(Object[] selection) { if (selection.length == 0) return new StatusInfo(IStatus.ERROR, ""); //$NON-NLS-1$ try { return checkException((IType)selection[0]); } catch (JavaModelException e) { JavaPlugin.log(e); return StatusInfo.OK_STATUS; } } }); if (dialog.open() == Window.OK) { return (IType) dialog.getFirstResult(); } return null; } private IStatus checkException(final IType type) throws JavaModelException { ITypeHierarchy hierarchy= type.newSupertypeHierarchy(new NullProgressMonitor()); IType curr= type; while (curr != null) { String name= curr.getFullyQualifiedName(); if ("java.lang.Throwable".equals(name)) //$NON-NLS-1$ return StatusInfo.OK_STATUS; curr= hierarchy.getSuperclass(curr); } return JavaUIStatus.createError(IStatus.ERROR, RefactoringMessages.ChangeExceptionsControl_not_exception, null); } private ExceptionInfo findExceptionInfo(IType exception) { for (Iterator<ExceptionInfo> iter= fExceptionInfos.iterator(); iter.hasNext(); ) { ExceptionInfo info= iter.next(); if (info.getElement().equals(exception)) return info; } return null; } private Button createRemoveButton(Composite buttonComposite) { final Button button= new Button(buttonComposite, SWT.PUSH); button.setText(RefactoringMessages.ChangeExceptionsControl_buttons_remove); button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); SWTUtil.setButtonDimensionHint(button); button.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { int index= getTable().getSelectionIndices()[0]; ExceptionInfo[] selected= getSelectedItems(); for (int i= 0; i < selected.length; i++) { if (selected[i].isAdded()) fExceptionInfos.remove(selected[i]); else selected[i].markAsDeleted(); } restoreSelection(index); } private void restoreSelection(int index) { fTableViewer.refresh(); fTableViewer.getControl().setFocus(); int itemCount= getTableItemCount(); if (itemCount != 0) { if (index >= itemCount) index= itemCount - 1; getTable().setSelection(index); } fListener.exceptionListChanged(); updateButtonsEnabledState(); } }); return button; } }